package com.itheima.sfbx.trade.face.impl;

import com.itheima.sfbx.framework.commons.constant.basic.CacheConstant;
import com.itheima.sfbx.trade.adapter.WapPayAdapter;
import com.itheima.sfbx.framework.commons.constant.trade.TradeCacheConstant;
import com.itheima.sfbx.framework.commons.enums.trade.TradeEnum;
import com.itheima.sfbx.framework.commons.exception.ProjectException;
import com.itheima.sfbx.trade.face.WapPayFace;
import com.itheima.sfbx.framework.commons.utils.ExceptionsUtil;
import com.itheima.sfbx.framework.commons.dto.trade.TradeVO;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @ClassName WapPayFaceImpl.java
 * @Description 手机网页支付Face接口实现
 */
@Slf4j
@Component
public class WapPayFaceImpl implements WapPayFace {

    @Autowired
    WapPayAdapter wapPayAdapter;

    @Autowired
    RedissonClient redissonClient;

    @Override
    public TradeVO wapTrade(TradeVO tradeVO) {
        //有可能会被多次点击而导致同时创建多个支付而支付多次的情况;所以需要对当前要支付的合同订单进行加 分布式锁
        //1、获取当前要创建支付订单的合同订单编号
        Long productOrderNo = tradeVO.getProductOrderNo();
        //2、获取分布式锁对象 对某个key获取锁(判断它是否存在与redis中:存在则说明已经被他人获取了锁,则等待:如果key不存在则设置key,说明加锁成功)
        RLock fairLock = redissonClient.getFairLock(TradeCacheConstant.CREATE_PAY + productOrderNo);
        try {
            //3、对合同订单编号添加分布式锁:
            if(fairLock.tryLock(TradeCacheConstant.REDIS_WAIT_TIME,  TradeCacheConstant.REDIS_LEASETIME,  TimeUnit.SECONDS)){
                //4、进行统一下单操作，创建交易单并返回交易订单信息
                return wapPayAdapter.wapTrade(tradeVO);
            } else {
                throw new ProjectException(TradeEnum.TRAD_PAY_FAIL);
            }

        } catch (InterruptedException e) {
            throw new RuntimeException("创建交易支付订单失败!"+e.getMessage());
        } finally {
            //5、释放分布式锁
            fairLock.unlock();
        }

//        //1、对交易订单加锁
//        Long productOrderNo = tradeVO.getProductOrderNo();
//        String key = TradeCacheConstant.CREATE_PAY + productOrderNo;
//        RLock lock = redissonClient.getFairLock(key);
//        try {
//            if (lock.tryLock(TradeCacheConstant.REDIS_WAIT_TIME, TimeUnit.SECONDS)){
//                return wapPayAdapter.wapTrade(tradeVO);
//            }else {
//                throw new ProjectException(TradeEnum.TRAD_PAY_FAIL);
//            }
//        } catch (Exception e) {
//            log.error("统一收单线下交易预创建异常:{}", ExceptionsUtil.getStackTraceAsString(e));
//            throw new ProjectException(TradeEnum.TRAD_PAY_FAIL);
//        }finally {
//            //释放锁
//            lock.unlock();
//        }
    }
}
